<template>
	<el-tree-select v-model="returnValue" clearable highlight-current accordion :render-after-expand="false"
		:expand-on-click-node="false" :check-strictly="checkStrictly" :data="data" :props="treeProps" :lazy="lazy"
		:load="load" class="v--tree-select">
		<template #default="{ data }">
			<slot name="label">{{ data[treeProps.label] }}</slot>
		</template>
	</el-tree-select>
</template>

<script setup>
import { computed, shallowRef, unref, watch } from "vue"
import { getAxios } from "/axios"

const props = defineProps({
	modelValue: {
		type: [String, Number],
		default: "",
	},
	list: {
		type: Array,
	},
	dict: {
		type: String,
	},
	label: {
		type: String,
		default: "name",
	},
	value: {
		type: String,
		default: "id",
	},
	children: {
		type: String,
		default: "children",
	},
	filed: {
		type: String,
		default: "id",
	},
	lazy: {
		type: Boolean,
		default: false,
	},
	checkStrictly: {
		type: Boolean,
		default: false,
	},
	itemDisabled: {
		type: Function,
	},
})

const emits = defineEmits(["update:modelValue", "change"])

const returnValue = computed({
	get() {
		if (props.modelValue === undefined || props.modelValue === null) {
			return ""
		}
		return props.modelValue + ""
	},
	set(value) {
		emits("update:modelValue", value)
	},
})
const treeProps = computed(() => {
	const value = props.value || (props.dict ? "code" : "value")
	const label = props.label || (props.dict ? "name" : "label")
	let disabled = _item => false
	if (props.itemDisabled) {
		disabled = props.itemDisabled
	}

	return {
		value,
		label,
		children: props.children,
		disabled,
	}
})
const data = shallowRef(props.list || [])
if (props.dict) {
	getTree().then(result => {
		data.value = result
	})
}

async function getTree(item) {
	return new Promise(async (resolve, reject) => {
		try {
			const result = await getAxios(props.dict, {
				[props.filed]: item[unref(treeProps).value],
			})
			resolve(result)
		} catch (error) {
			reject(error)
		}
	})
}
async function load(node, resolve) {
	if (Array.isArray(node.data)) return
	if (node.data.children?.length) {
		return resolve(node.data.children)
	}
	try {
		const result = await getTree(node.data)
		resolve(result)
	} catch (error) {
		resolve([])
	}
}

watch(
	() => props.list,
	() => {
		data.value = props.list || []
	}
)
</script>

<style lang="scss" scoped></style>
